package com.tetris

import androidx.compose.runtime.Composable
import androidx.compose.runtime.MutableIntState
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.geometry.Size
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.drawscope.DrawScope

import java.util.Random

// 格
open class Grid {
    var mUsed: Boolean = false  // 使用则为 true，否则为 false
}

// 带颜色的格
class ColorGrid: Grid() {
    var mColor = Color.Unspecified  // 颜色
}

// 方块
abstract class Block {
    // 形状
    protected enum class Shape {
        ONE,    // 形状1
        TWO,    // 形状2
        THREE,  // 形状3
        FOUR    // 形状4
    }

    protected val mBlocks: Array<Array<Grid>>           // 方块数据
    protected val mColor: Color                         // 颜色
    protected lateinit var mLine: MutableIntState       // 当前所在列(左)
    protected lateinit var mRow: MutableIntState        // 当前所在行(上)
    protected lateinit var mShape: MutableState<Shape>  // 形状

    companion object {
        /**
         * 画矩形的边框，使矩形具有立体效果。
         * @param drawer    绘图者
         * @param left, top 矩形的左上角坐标
         */
        fun drawEdge(drawer: DrawScope, left: Float, top: Float) {
            val right = left + Const.GRID_SIZE - 1f
            val bottom = top + Const.GRID_SIZE - 1f

            drawer.drawLine(Const.COLOR_LEFT_TOP_1, Offset(left, top), Offset(right, top))
            drawer.drawLine(Const.COLOR_LEFT_TOP_1, Offset(left, top), Offset(left, bottom))

            drawer.drawLine(Const.COLOR_LEFT_TOP_2, Offset(left + 1f, top + 1f), Offset(right - 1f, top + 1f))
            drawer.drawLine(Const.COLOR_LEFT_TOP_2, Offset(left + 1f, top + 1f), Offset(left + 1f, bottom - 1f))

            drawer.drawLine(Const.COLOR_RIGHT_BOTTOM_1, Offset(right, top), Offset(right, bottom))
            drawer.drawLine(Const.COLOR_RIGHT_BOTTOM_1, Offset(left, bottom), Offset(right, bottom))

            drawer.drawLine(Const.COLOR_RIGHT_BOTTOM_2, Offset(right - 1f, top + 1f), Offset(right - 1f, bottom - 1f))
            drawer.drawLine(Const.COLOR_RIGHT_BOTTOM_2, Offset(left + 1f, bottom - 1f), Offset(right - 1f, bottom - 1f))
        }
    }

    /**
     * 构造方法。
     */
    constructor() {
        mBlocks = Array<Array<Grid>>(Const.BLOCK_GRID_COUNT_V) {
            Array<Grid>(Const.BLOCK_GRID_COUNT_H) {
                Grid()
            }
        }
        val maxValue = Byte.Companion.MAX_VALUE * 2 + 1
        val random = Random()   // 随机数生成器
        mColor = Color(random.nextInt(maxValue), random.nextInt(maxValue), random.nextInt(maxValue))
    }

    /**
     * 获取底端所在的行数。底端是指方块最下方的有效格。
     */
    abstract val bottom: Int

    /**
     * 绘制自身。
     * @param drawer    绘图者
     */
    fun draw(drawer: DrawScope) {
        for (i in 0 ..< Const.BLOCK_GRID_COUNT_H) {
            for (j in 0 ..< Const.BLOCK_GRID_COUNT_V) {
                // 遍历所有格，跳过无效的，画有效的
                if (!mBlocks[i][j].mUsed) {
                    continue
                }

                val left = Const.GRID_SIZE * (mLine.intValue + j)
                val top = Const.GRID_SIZE * (mRow.intValue + i)
                mShape.value
                drawer.drawRect(mColor,
                    Offset(Const.GRID_SIZE * (mLine.intValue + j), Const.GRID_SIZE * (mRow.intValue + i)),
                    Size(Const.GRID_SIZE, Const.GRID_SIZE)
                )
                drawEdge(drawer, left, top)
            }
        }
    }

    /**
     * 进入预览区域。
     * @param previewWidth  预览区域宽度
     * @param previewHeight 预览区域高度
     * @param drawer        绘图者
     */
    open fun enterPreview(previewWidth: Float, previewHeight: Float, drawer: DrawScope) {
        val x = (previewWidth - Const.GRID_SIZE * 3f) / 2f
        val y = previewHeight / 2f - Const.GRID_SIZE * 2f

        // 遍历所有格，跳过无效的，画有效的
        for (i in 0 ..< Const.BLOCK_GRID_COUNT_H) {
            for (j in 0 ..< Const.BLOCK_GRID_COUNT_V) {
                if (!mBlocks[i][j].mUsed) {
                    continue
                }
                drawer.drawRect(mColor, Offset(x + Const.GRID_SIZE * j, y + Const.GRID_SIZE * i), Size(Const.GRID_SIZE, Const.GRID_SIZE))
                drawEdge(drawer, x + Const.GRID_SIZE * j, y + Const.GRID_SIZE * i)
            }
        }
    }

    /**
     * 对不能下落的处理。
     */
    protected abstract fun handleCannotMoveDown()

    /**
     * 初始化。
     */
    @Composable
    fun Init() {
        mLine = remember {
            mutableIntStateOf(3)
        }
        mRow = remember {
            mutableIntStateOf(-1)
        }
        mShape = remember {
            mutableStateOf(Shape.ONE)
        }
    }

    /**
     * 下落。
     * @return 总是 true
     */
    open fun moveDown(): Boolean {
        mRow.intValue++
        return true
    }

    /**
     * 左移。
     */
    open fun moveLeft() {
        mLine.intValue--
    }

    /**
     * 右移。
     */
    open fun moveRight() {
        mLine.intValue++
    }

    /**
     * 获取顶端所在的行数。顶端是指方块最上方的有效格。
     */
    abstract val top: Int

    /**
     * 变形。
     */
    abstract fun transform()
}
